package client;

import static debug.Debug.DBUG;

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;

import event.AlfaEvent;
import event.EventParser;
import event.UnitEvent;

import model.Map;

import server.Server;
import unit.Player;
import unit.Unit;
import util.IntPoint;

public class ClientPlayer extends Player implements Runnable {
	private static final int STEP_LENGTH = 3;
	private BufferedReader in;
	private Server server;
	private ClientControl clientcontrol;
	
	private int direction;
	private int speed;
	private boolean moving;
	
	private List<AlfaEvent> eventlist;
	
	public ClientPlayer(int id, IntPoint start, Map mapStart, ClientControl cc, Server serv) {
		super(id, start, mapStart);
		
		eventlist = new ArrayList<AlfaEvent>();
	
		server = serv;
		this.clientcontrol = cc;
		in = cc.getInput(); 
		new Thread(this).start();
		DBUG("ClientPlayer constructor: "+ id);
	}
	
	public void moveTo(IntPoint target){
		move(target);
	}
	
	public int getY() {
		return getPos().getY();
	}
	public int getX() {
		return getPos().getX();
	}

	public void tick() {
		if (moving) {
			IntPoint nextpos = getPos();
			nextpos.incDir(direction, speed);
			move(nextpos);
		}
		super.tick();
	}
	
	@Override
	public boolean equals(Object cca) {
		try {
			ClientPlayer p = (ClientPlayer)cca;
			if (p.id() == id()) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
	}

	public void fireEvent(AlfaEvent event){
		eventlist.add(event);
	}
	
	@Override
	public void run() {
		String inline;
		while (true) {
			try {
				inline = in.readLine();
				if (inline == null) {
					in.close();
					return;
				}
			} catch (IOException e) {
				DBUG("failed to read");
				try { in.close(); } catch (IOException e1) {}
				return;
			}
			int chan=0;
			String[] parts = inline.split(" ");
			if (parts[0].equals("moving")) {
				int dir=Integer.parseInt(parts[1]);
				int spd=Integer.parseInt(parts[2]);
				direction=dir;
				speed=spd;
				moving=true;
			} else if (parts[0].equals("movestop")) {
				moving=false;
			} else if (parts[0].equals("move")) {
				chan=55;
				int xx=Integer.parseInt(parts[1]);
				int yy=Integer.parseInt(parts[2]);
				moveTo(new IntPoint(xx, yy));
			}else if(parts[0].equals("event")){
				int toid = Integer.parseInt(parts[1]);
				String event = parts[2];
				String params = parts[3];
				Unit unit = server.getUnitByID(toid);
				AlfaEvent e = EventParser.parseEvent(id(), -1, parts[2], parts[3]);
				unit.fireEvent(e);
			}
			DBUG(chan, "cp< "+ inline);
		}
	}

	public List<AlfaEvent> getEvents() {
		List<AlfaEvent> newList = copyList(eventlist);
		eventlist.clear();
		return newList;
	}

	private List<AlfaEvent> copyList(List<AlfaEvent> list){
		List<AlfaEvent> newList = new ArrayList<AlfaEvent>();
		for(AlfaEvent event:list){
			newList.add(event);
		}
		return newList;
	}
}
